<template>
	<view class="wrapper">
		<cx-bill-canceled v-if="labelData.isCancel" />

		<u-navbar title="标签入库" :autoBack="true" :safeAreaInsetTop="false" :fixed="false">
			<view slot="right" @tap="navBarClick">
				<u-icon name="setting" size="19"></u-icon>
			</view>
		</u-navbar>
		<!-- <Setting ref="setting" :showFileds="showFileds" @on-sure="onSettingSure" /> -->
		<cx-scan-progress v-if="oper === 'fromBill'" class="p-20" :current="piecesCountProgress.current"
			:total="piecesCountProgress.total" />

		<view class="content">
			<!-- labelData:{{labelData}} -->
			<u-cell-group>
				<u-cell :isLink="true" arrow-direction="right" @click="btnSelectGoods">
					<view slot="title" class="flex f-36">
						<view class="w-100 c-99">
							产品:
						</view>
						<view class="flex-1">
							{{labelData.code || ''}} /
							{{labelData.name || ''}}
						</view>
					</view>
				</u-cell>
				<u-cell title="颜色" :isLink="true" arrow-direction="right" @click="btnSelectColor">
					<view slot="title" class="flex f-36">
						<view class="w-100 c-99">
							颜色:
						</view>
						<view class="flex-1">
							{{labelData.colorNumber || ''}} /
							{{labelData.color || ''}}
						</view>
					</view>
				</u-cell>
				<u-cell>
					<view slot="title" class="flex f-36">
						<view class="flex-sb">
							<view class="flex-1 flex-sb">
								<view class="w-100 c-99 p-t-10">
									幅宽:
								</view>
								<view class="flex-1">
									<u-input :disabled="oper === 'edit'" v-model="labelData.widthValue" />
								</view>
							</view>

							<view class="flex-1 flex-sb p-l-20">
								<view class="w-100 c-99 p-t-10">
									克重:
								</view>
								<view class="flex-1">
									<u-input :disabled="oper === 'edit'" v-model="labelData.gramWeightValue" />
								</view>
							</view>
							
							<view class="flex-sb p-l-10">
								<cx-select-goods-width :spuId="labelData.spuId" :disabled="oper === 'edit'"
									@on-selected="onWidthGramWeightSelected" />
							</view>
						</view>
					</view>
				</u-cell>

				<u-gap bgColor="#eee"></u-gap>
				<u-cell title="仓库" :isLink="true" arrow-direction="right" @click="btnSelectStore">
					<view slot="title" class="flex f-36">
						<view class="w-100 c-99">
							仓库:
						</view>
						<view class="flex-1">
							{{labelData.storeName || ''}}
						</view>
					</view>
				</u-cell>
				<u-cell title="仓位" :isLink="true" arrow-direction="right" @click="btnSelectStorePosition">
					<view slot="title" class="flex f-36">
						<view class="w-100 c-99">
							仓位:
						</view>
						<view class="flex-1">
							{{labelData.positionName || ''}}
						</view>
					</view>
				</u-cell>
				<u-gap bgColor="#eee"></u-gap>
				<u-cell title="单位" :isLink="true" arrow-direction="right" @click="btnSelectUnit">
					<view slot="title" class="flex f-36">
						<view class="w-100 c-99">
							单位:
						</view>
						<view class="flex-1">
							{{labelData.unitName || ''}}
						</view>
					</view>
				</u-cell>
				<u-cell v-if="showFileds.includes('spec')">
					<view slot="title" class="flex f-36">
						<view class="w-100 c-99 p-t-10">
							规格:
						</view>
						<view class="flex-1">
							<u-input :disabled="!canEditGoods" v-model="labelData.spec" />
						</view>
					</view>
				</u-cell>
				<u-cell v-if="showFileds.includes('vatNo')">
					<view slot="title" class="flex f-36">
						<view class="w-100 c-99 p-t-10">
							缸号:
						</view>
						<view class="flex-1">
							<u-input :disabled="!canEditGoods" v-model="labelData.vatNo" />
						</view>
					</view>
				</u-cell>
				<u-cell v-if="showFileds.includes('batchNumber')">
					<view slot="title" class="flex f-36">
						<view class="w-100 c-99 p-t-10">
							批次:
						</view>
						<view class="flex-1">
							<u-input :disabled="!canEditGoods" v-model="labelData.batchNumber" />
						</view>
					</view>
				</u-cell>
				<u-cell v-if="showFileds.includes('volumeNo')">
					<view slot="title" class="flex f-36">
						<view class="w-100 c-99 p-t-10">
							卷号:
						</view>
						<view class="flex-1">
							<u-input :disabled="!canEditGoods" v-model="labelData.volumeNo" />
						</view>
					</view>
				</u-cell>
				<u-cell>
					<view slot="title" class="flex f-36">
						<view class="w-100 p-t-10 fw-medium c-orange">
							数量:
						</view>
						<view class="flex-1">
							<u-input v-model="labelData.quantity" />
						</view>
					</view>
				</u-cell>
				<u-cell>
					<view slot="title" class="flex f-36">
						<view class="flex-sb">
							<view class="flex-1 flex-sb">
								<view class="w-240 c-99 p-t-10" @tap="$refs.selectSpace.open()">
									空差模式 > <text class="f-46 p-l-20">{{labelData.spaceDiffTypeName}}</text>
								</view>
								<view class="flex-1">
									<select-space-diff-type ref="selectSpace" v-model="labelData.spaceDiffType"
										:label.sync="labelData.spaceDiffTypeName" />
								</view>
							</view>

							<view class="flex-1 flex-sb p-l-20">
								<view class="w-100 c-99 p-t-10">
									空差:
								</view>
								<view class="flex-1">
									<u-input v-model="labelData.spaceDiffValue" />
								</view>
							</view>
						</view>
					</view>
				</u-cell>
				<u-cell>
					<view slot="title" class="flex f-36">
						<view class="w-130 p-t-10 fw-medium c-orange">
							实布数:
						</view>
						<view class="flex-1">
							<u-input disabled v-model="labelData.realQuantity" />
						</view>
					</view>
				</u-cell>
				<u-cell v-if="showFileds.includes('remarks')">
					<view slot="title" class="flex f-36">
						<view class="w-100 c-99 p-t-10">
							备注:
						</view>
						<view class="flex-1">
							<u-input v-model="labelData.remarks" />
						</view>
					</view>
				</u-cell>
			</u-cell-group>
		</view>

		<view class="btns p-20">
			<u-row gutter="10" v-if="['edit'].includes(oper) && !labelData.isCancel">
				<u-col span="6">
					<u-button type="primary" @tap="btnSaveData">保存</u-button>
				</u-col>
				<u-col span="6">
					<u-button type="error" @tap="btnCancel">作废</u-button>
				</u-col>
			</u-row>

			<u-row gutter="10" v-if="['add','fromBill'].includes(oper)">
				<u-col span="6">
					<u-button type="primary" @tap="btnStockInAndPrint">入库并打印</u-button>
				</u-col>
				<u-col span="6">
					<u-button @tap="btnOnlyStockIn">仅入库</u-button>
				</u-col>
			</u-row>
		</view>


		<!-- 作废 -->
		<u-modal style="position: absolute;" v-show="isModalShow" :show="isModalShow" title="确定要作废本次入库记录吗？"
			:closeOnClickOverlay="true" @close="isModalShow = false" @confirm="confirmCancel">
			<view class="slot-content">
				<view class="flex-sb m-t-20">
					<text class="c-99">同时生成一条一样的入库记录：</text>
					<u-switch v-model="labelData.isGenerateSameBill"></u-switch>
				</view>
			</view>
		</u-modal>
	</view>
</template>

<script>
	import Schema from 'async-validator';

	import {
		addData,
		cancel,
		updateData,
		getVoById,
		getDefaultPrintTemplate
	} from '@/apis/bill/label-stock.js'

	import {
		getById
	} from '@/apis/goods/goods.js'

	import Setting from './components/setting.vue'


	import {
		initFromBillData,
		initUpdateData,
		initManualData
	} from './init.js'

	import {
		initCanvas,
		printStaticText,
		printFieldText,
		printMemoBox,
		printQrCode,
		printBarcode,
		printLine,
		printCanvas
	} from './print-utils.js'

	const localStoreKey = "snStockFileds"

	export default {
		components: {
			Setting
		},
		data() {
			return {
				// 操作方式
				oper: 'add',
				// 入库记录的id
				id: null,
				// 标签Data
				labelData: {
					name: ""
				},
				piecesCountProgress: {},
				isModalShow: false,
				modalTitle: "提示",
				// 列表页面显示的字段
				showFileds: [],
				listData: [],
				rules: {
					quantity: {
						type: 'number',
						required: true,
						asyncValidator: (rule, value) => {
							return new Promise((resolve, reject) => {
								if (Number(value || 0) <= 0) {
									reject('入库数量不能为0'); // reject with error message
								} else {
									resolve();
								}
							})
						}
					}
				}
			}
		},
		computed: {
			// 是否可编辑商品信息
			canEditGoods: function() {
				const labelData = this.labelData || {}
				return true
			},
			// 实布数
			realQuantity: function() {
				const labelData = this.labelData || {}
				const quantity = Number(labelData.quantity || 0)
				const spaceDiffType = labelData.spaceDiffType

				const spaceDiffValue = Number(labelData.spaceDiffValue || 0)
				if (spaceDiffType === 0) return quantity + spaceDiffValue
				if (spaceDiffType === 1) return quantity * spaceDiffValue
				if (spaceDiffType === 2) return quantity / spaceDiffValue

			}
		},
		watch: {
			"realQuantity": {
				handler(val) {
					this.$set(this.labelData, 'realQuantity', val)
				},
				immediate: true
			}
		},
		onLoad() {
			this.labelData = {}

			// 1. 缓存
			this.showFileds = this.$ls.get(localStoreKey) || []

			const id = this.$Route.query.id
			const oper = this.$Route.query.oper
			this.id = id
			this.oper = oper
			// 1. 编辑
			if (oper === 'edit' && id) {
				initUpdateData.bind(this)(id)
				return
			}

			if (oper === 'fromBill') {
				initFromBillData.bind(this)()
				return
			}

			initManualData.bind(this)()
		},
		onReady() {
			uni.$on("on-selected-goods", data => {
				this.$set(this.labelData, 'spuId', data.spuId)
				this.$set(this.labelData, 'code', data.code)
				this.$set(this.labelData, 'name', data.name)

				this.$set(this.labelData, 'colorId', null)
				this.$set(this.labelData, 'color', null)
				this.$set(this.labelData, 'colorNumber', null)
				const spuId = data.spuId
				if (!spuId) return
				getById(spuId).then(res => {
					if (!res.data.flag) return
					const data = res.data.data || {}
					this.$set(this.labelData, 'unitId', data.unitId)
					this.$set(this.labelData, 'unitName', data.unitName)
				})
			})
			uni.$on("on-selected-goods-color", data => {
				this.$set(this.labelData, 'colorId', data.id)
				this.$set(this.labelData, 'color', data.color)
				this.$set(this.labelData, 'colorNumber', data.colorNumber)
			})
			uni.$on("on-selected-store", data => {
				this.$set(this.labelData, 'storeId', data.id)
				this.$set(this.labelData, 'storeName', data.name)
			})
			uni.$on("on-selected-store-position", data => {
				this.$set(this.labelData, 'positionId', data.value)
				this.$set(this.labelData, 'positionName', data.label)
			})
			uni.$on("on-selected-unit", data => {
				this.$set(this.labelData, 'unitId', data.value)
				this.$set(this.labelData, 'unitName', data.label)
			})
		},
		methods: {
			// 编辑保存
			btnSaveData() {
				const params = this.labelData
				uni.showLoading({
					title: "保存中"
				})
				updateData(params).then(res => {
					if (!res.data.flag) {
						uni.showToast({
							icon: 'error',
							title: res.data.message
						})
						return
					}
					uni.showToast({
						icon: 'success',
						title: res.data.title
					})
				}).finally(_ => {
					uni.hideLoading()
				})
			},
			btnCancel() {
				this.isModalShow = true
			},
			confirmCancel() {
				uni.showLoading({
					title: "作废中"
				})
				const params = {
					billId: this.id,
					isGenerateSameBill: this.labelData.isGenerateSameBill
				}
				cancel(params).then(res => {
					if (!res.data.flag) return
					const data = res.data.data || {}
					this.labelData = data
					this.isModalShow = false
				}).finally(_ => {
					uni.hideLoading()
				})
			},
			btnStockInAndPrint() {
				const params = this.labelData
				this.validate().then(_ => {
					this.stockIn(params).then(data => {
						const labelData = {
							...data.goodsSnStockVO
						}
						const snVoList = labelData.snVoList
						const snVo = snVoList[0]
						labelData["sn"] = snVo.sn
						uni.showLoading({
							title: "获取打印模板"
						})
						getDefaultPrintTemplate().then(res => {
							if (!res.data.flag) return
							const data = res.data.data
							const template = data.template || {}
							this.printData(template, labelData)
						}).finally(_ => {
							uni.hideLoading()
						})
					})
				}).catch(err => {
					uni.showToast({
						icon: "error",
						title: err.message
					})
				})
			},
			btnOnlyStockIn() {
				this.validate().then(_ => {
					const params = this.labelData
					this.stockIn(params)
				}).catch(err => {
					uni.showToast({
						icon: "error",
						title: err.message
					})
				})
			},
			btnSelectGoods() {
				if (!this.canEditGoods) return
				this.$Router.push({
					name: "SelectGoods"
				})
			},
			btnSelectColor() {
				if (!this.canEditGoods) return
				const spuId = this.labelData.spuId
				if (!spuId) {
					uni.showToast({
						icon: 'error',
						title: "请先选择产品"
					})
					return
				}
				this.$Router.push({
					path: "/selects/goods-color",
					query: {
						spuId
					}
				})
			},
			btnSelectStore() {
				if (!this.canEditGoods) return
				this.$Router.push({
					name: "SelectStore"
				})
			},
			btnSelectStorePosition() {
				if (!this.canEditGoods) return
				const storeId = this.labelData.storeId
				if (!storeId) {
					uni.showToast({
						icon: 'error',
						title: "请先选择仓库"
					})
					return
				}
				this.$Router.push({
					path: "/selects/storePosition",
					query: {
						storeId
					}
				})
			},
			btnSelectUnit() {
				if (!this.canEditGoods) return
				this.$Router.push({
					name: "SelectUnit"
				})
			},
			/**
			 * 标签入库
			 */
			stockIn(params) {
				uni.showLoading({
					title: "入库中"
				})
				return new Promise((resovel, reject) => {
					addData(params).then(res => {
						if (!res.data.flag) {
							uni.showToast({
								icon: 'error',
								title: res.data.message
							})
							return
						}
						this.$set(this.labelData, 'quantity', 0)
						uni.showToast({
							icon: 'success',
							title: res.data.title
						})
						const data = res.data.data || {}
						const detailPiecesCountProgress = data.detailPiecesCountProgress || {}
						this.piecesCountProgress = detailPiecesCountProgress
						resovel(res.data.data || {})
					}).finally(_ => {
						uni.hideLoading()
					})
				})
			},
			validate() {
				const validator = new Schema(this.rules);
				const data = this.labelData
				console.log("validator", validator, data)
				return new Promise((resovel, reject) => {
					validator.validate(data, (errors, fields) => {
						console.log('errors', errors)
						if (errors) {
							const error = errors[0]
							return reject(new Error(error.message))
						}
						resovel()
					})
				})
			},
			/**
			 * 打印标签
			 * @param {模板数据} template
			 * @param {标签数据} labelData
			 */
			printData(template, labelData) {
				uni.showLoading({
					title: "开始打印"
				})
				const Printer = template.Printer
				const DetailGrid = template.DetailGrid || {}
				const Recordset = DetailGrid.Recordset || {}
				// 绑定的字段
				const Field = Recordset.Field || []
				const ColumnContent = DetailGrid.ColumnContent || {}
				const ColumnContentCellList = ColumnContent.ColumnContentCell || []

				const Width = Printer.Width
				const Height = Printer.Height

				// 1. 初始化打印面板
				initCanvas(Width, Height)

				const ColumnContentCell = ColumnContentCellList[0]
				const Control = ColumnContentCell.Control || []

				Control.forEach(item => {

					// console.log('item:', item)

					const Type = item['Type']
					const Left = item['Left']
					const Top = item['Top']
					const Width = item['Width']
					const Height = item['Height']

					// 文字
					if (Type === 'StaticBox') {
						printStaticText(item)
					}
					// 绑定文字
					if (Type === 'FieldBox') {
						printFieldText(item, Field, labelData)
					}
					
					// 综合文本
					if (Type === 'MemoBox') {
						printMemoBox(item, Field, labelData)
					}

					// 二维码
					if (Type === 'Barcode' && item['BarcodeType'] === 'QRCode') {
						printQrCode(item, Field, labelData)
					}

					// 条码
					if (Type === 'Barcode' && item['BarcodeType'] === 'Code128C') {
						printBarcode(item, Field, labelData)
					}

					// 线条
					if (Type === 'Line') {
						printLine(item)
					}
				})
				printCanvas(1)
				uni.hideLoading()
			},
			navBarClick() {
				this.$refs.setting.open()
			},
			/**
			 * 根据名称获取绑定的字段key
			 */
			getBindFiledByName(name, Field = []) {
				const targetFiled = Field.find(item => {
					return item.Name === name
				})
				if (targetFiled) {
					return targetFiled.DBFieldName
				}
			},
			onWidthGramWeightSelected(data) {
				const widthValue = data.widthValue
				const gramWeightValue = data.gramWeightValue
				this.$set(this.labelData, "widthValue", widthValue)
				this.$set(this.labelData, "gramWeightValue", gramWeightValue)
			},
			onSettingSure(data) {
				this.showFileds = data
				this.$ls.set(localStoreKey, data)
			}
		}
	}
</script>

<style lang="scss" scoped>
	.wrapper {
		display: flex;
		flex-direction: column;
		height: 100%;
		background-color: #fff;

		.content {
			flex: 1;
			overflow-y: scroll;
		}

		.btns {}
	}
</style>